/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.extensionpoints.palette;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.IConfigurationElement;

import com.cea.papyrus.core.extensionpoints.AbstractExtensionPoint;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.core.utils.UMLObjectActionFilter;

/**
 * 
 */
public class Element extends AbstractExtensionPoint {
	
	/** Debug channel */
	private static final int channel = 21;

	/**
	 * 
	 */
	public final IConfigurationElement	configElement;
	
	/**
	 * 
	 */
	private final String type;
	
	/**
	 * 
	 */
	private final String kind;	
	
	/**
	 * 
	 */
	private final Stereotype[] stereotypes;
	
	/**
	 * 
	 * 
	 * @param ordinal 
	 * @param configElt 
	 * 
	 * @return 
	 */
	public static Element parse(IConfigurationElement configElt, int ordinal) {
		
		if (!configElt.getName().equals(IConstants.TAG_ELEMENT)) {
			return null;
		}
		
		try {
			return new Element(configElt);
			
		} catch (Exception e) {
			
			String name = configElt.getAttribute(IConstants.ATT_STEREOTYPE_NAME);
			if (name == null) {
				name = "[missing name attribute]";
			}
			String msg = "Failed to load stereotype element named "
							+ name + " in "
							+ configElt
								.getDeclaringExtension()
								.getExtensionPointUniqueIdentifier();
			
			Debug.debug(null, msg, channel );
			return null;
		}
	}
	
	/**
	 * 
	 * 
	 * @param ordinal 	 * @param configElt 
	 */
	public Element(IConfigurationElement configElt) {
		this.configElement = configElt;

		type  = getAttribute(configElt, IConstants.ATT_ELEMENT_TYPE, null, true);
		kind  = getAttribute(configElt, IConstants.ATT_ELEMENT_KIND, null, false);
		
		// Retrieving properties
		IConfigurationElement[] stChildren = configElt.getChildren(IConstants.TAG_STEREOTYPE);
		if (stChildren == null) {
			stereotypes = null;
			return;
		}
			
		List<Stereotype> stList = new ArrayList<Stereotype>();
		// Read properties
		for (int i = 0 ; i < stChildren.length ; i++) {
			Stereotype proxy = Stereotype.parse(stChildren[i], stList.size());

			if (proxy != null) {
				stList.add(proxy);
			}
		} // end of configElements loop	

		stereotypes = stList.toArray(new Stereotype[stList.size()]);
	}
	
	/**
	 * Default constructor.
	 * 
	 * @param uri 	 */
	public Element() {
		this.configElement = null;
		
		type        = "undefined";
		kind        = "undefined";
		stereotypes = null;
	}
	
	/**
	 * 
	 * 
	 * @param element 
	 * 
	 * @return 
	 */
	public boolean matchType(org.eclipse.uml2.uml.Element element) {
		
		UMLObjectActionFilter tester = new UMLObjectActionFilter();

		// Test type
		if (! (tester.testAttribute(element, UMLObjectActionFilter.ATT_UMLType, getType()))) {
			return false;
		}
		// Test kind
		// ...todo
		
		// Test Stereotype
		Stereotype[] stereotypes = getStereotypes();
		if ((stereotypes == null) || (stereotypes.length < 1)) {
			return true;
		}
		
		// else test each stereotype
		for (int i = 0; i < stereotypes.length; i++) {
			if (! (tester.testAttribute(element, UMLObjectActionFilter.ATT_Stereotype, stereotypes[i].getName()))) {
				return false;
			}
		}
		
		// Test Properties
		// ...todo
		
		return true;
	}

	/**
	 * 
	 * 
	 * @return 
	 */
	public String getType() {
		return type;
	}
	
	/**
	 * 
	 * 
	 * @return 
	 */
	public String getKind() {
		return kind;
	}

	/**
	 * 
	 * 
	 * @return 
	 */
	public Stereotype[] getStereotypes() {
		return stereotypes;
	}
	
}
